package com.springboot.aspect;


import com.springboot.enums.CodeEnum;
import com.springboot.exceptions.ErrorCodeException;
import com.springboot.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;


/**
 * @author coDing
 */
@Aspect
@Component
@Slf4j
public class TokenatureValidation {

    /**
     * 时间戳请求最大限制
     */
    private static final long MAX_REQUEST = 300000 * 1000L;

    /**
     * Redis 工具类
     */
    @Resource
    private RedisUtil redisUtil;
    /**
     * 验签切点
     */
    @Pointcut("execution(@com.springboot.aop.TokenatureValidation * *(..))")
    private void verifyUserKey() {
    }

    /**
     * 开始验签
     */
    @Before("verifyUserKey()")
    public void doBasicProfiling() {
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        String token = request.getHeader("token");
        String timestamp = request.getHeader("timestamp");
        try {
            if (StringUtils.isAnyBlank(token, timestamp)) {
                throw new ErrorCodeException(CodeEnum.TOKON_ERROR);
            }
            long now = System.currentTimeMillis();
            long time = Long.parseLong(timestamp);
            if (now - time > MAX_REQUEST) {
                log.error("时间戳已过期[{}][{}][{}]", now, time, (now - time));
                throw new ErrorCodeException(CodeEnum.HTTP_CONNECTION_OVERTIME);
            }
            if (!redisUtil.hasKey(token)) {
                log.error("请求token[{}],timestamp[{}]-vs-服务器token[{}]", token, timestamp);
                throw new ErrorCodeException(CodeEnum.TOKON_ERROR);
            }else{
                redisUtil.expire(token,600);
            }
        } catch (Throwable throwable) {
            throw new ErrorCodeException(CodeEnum.ERROR);
        }

    }



}
